/**
 * ReportGear(2011)
 */
package net.abbp.report.view.cell.editor;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import net.abbp.report.model.Cell;
import net.abbp.report.view.cell.value.JsDataValue;
import net.abbp.report.view.grid.Grid;
import net.abbp.swing.layout.LayoutUtils;

import com.reportgear.core.swing.pane.base.EditorPane;
import com.reportgear.core.swing.pane.base.JBaseDialog;
import net.abbp.core.util.StringUtils;
import com.reportgear.report.core.api.idname.IdName;
import com.reportgear.report.data.datasource.JsDataSource;
import com.reportgear.report.data.datasource.JsDataSourceFactory;

/**
 * JsDataFieldObject 编辑器
 * 
 * @version 1.0 2011-7-27
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class JsDataValueEditor extends AbstractCellEditor {
    private JsDataValue value;

    @Override
    public Component getCellEditorComponent(Grid grid, Cell cell) {
        JsDataFieldObjectEditPane editorPane = new JsDataFieldObjectEditPane();

        editorPane.populate((JsDataValue) cell.getValue());

        if (editorPane.showDialog(grid) == JBaseDialog.RESULT_OK) {
            this.value = editorPane.update();
        }

        return null;
    }

    @Override
    public Object getCellEditorValue() {
        return this.value;
    }

    private static class JsDataFieldObjectEditPane extends EditorPane<JsDataValue> {
        /**
         * UID
         */
        private static final long serialVersionUID = 7066129706219244594L;
        private JsDataValue value;
        private JComboBox cbxDataSource;
        private TypePane typePane;
        private JCheckBox chkExpand;

        JsDataFieldObjectEditPane() {
            this.setBorder(BorderFactory.createEtchedBorder());
            this.setLayout(new GridBagLayout());
            this.cbxDataSource = new JComboBox(JsDataSourceFactory.INSTANCE.getDataSourceList().toArray(new IdName[0]));
            this.cbxDataSource.addActionListener(new ActionListener() {

                @SuppressWarnings("unchecked")
                @Override
                public void actionPerformed(ActionEvent e) {
                    JComboBox cbx = (JComboBox) e.getSource();

                    Object selected = cbx.getSelectedItem();
                    if (selected != null) {
                        IdName<String> ds = (IdName<String>) cbx.getSelectedItem();
                        JsDataSource jds = JsDataSourceFactory.INSTANCE.getDataSource(ds.getId());
                        typePane.setFields(jds.getFields());
                    }
                }
            });
            this.cbxDataSource.setPreferredSize(new Dimension(300, 24));

            this.add(new JLabel("数据源", SwingConstants.LEFT), LayoutUtils.newGridBagConstraints(0, 0, 1, 1));
            this.add(this.cbxDataSource, LayoutUtils.newGridBagConstraints(1, 0, 1, 1));
            this.typePane = new TypePane();
            this.add(this.typePane, LayoutUtils.newGridBagConstraints(0, 1, 2, 1));
            this.chkExpand = new JCheckBox("扩展");
            this.add(this.chkExpand, LayoutUtils.newGridBagConstraints(0, 2, 1, 1));
            
            this.cbxDataSource.setSelectedIndex(0);

        }

        @Override
        public void populate(JsDataValue value) {
            this.value = value;

            this.chkExpand.setSelected(value.isExpand());

            String id = value.getDataSourceId();
            if (StringUtils.isEmpty(id)) {
                return;
            }

            for (int i = 0, size = this.cbxDataSource.getItemCount(); i < size; i++) {
                @SuppressWarnings("unchecked")
                IdName<String> item = (IdName<String>) cbxDataSource.getItemAt(i);

                if (id.equals(item.getId())) {
                    cbxDataSource.setSelectedIndex(i);

                    break;
                }
            }

            this.typePane.populate(value);
        }

        @Override
        public int showDialog(Component owner) {
            return this.showDialog(SwingUtilities.getWindowAncestor(owner), "履历信息", 460, 220);
        }

        @Override
        public JsDataValue update() {
            @SuppressWarnings("unchecked")
            IdName<String> item = (IdName<String>) this.cbxDataSource.getSelectedItem();

            if (item != null) {
                this.value.setDataSourceId(item.getId());
                this.value.setDataSourceCaption(item.getName());
            }

            this.typePane.update(this.value);

            this.value.setExpand(this.chkExpand.isSelected());
            return this.value;
        }
    }

    /**
     * 类型面板
     * 
     */
    private static class TypePane extends JPanel {
        /**
         * UID
         */
        private static final long serialVersionUID = -3557505032932953835L;
        private JRadioButton rbtnNormal;
        private JRadioButton rbtnPhoto;
        private JRadioButton rbtnFormula;

        private JLabel lblField;
        private JComboBox cbxField;
        private JLabel lblFormula;
        private JTextField txtFormula;

        private TypePane() {
            this.initComponents();
        }

        /**
         * @param fields
         */
        public void setFields(List<IdName<String>> fields) {
            DefaultComboBoxModel model = (DefaultComboBoxModel) cbxField.getModel();
            model.removeAllElements();

            for (IdName<String> idn : fields) {
                model.addElement(idn);
            }
        }

        private void initComponents() {
            this.setLayout(new BorderLayout());

            JPanel paneBtns = new JPanel();
            this.add(paneBtns, BorderLayout.NORTH);

            ButtonGroup bg = new ButtonGroup();
            this.rbtnNormal = new JRadioButton("字段", true);
            this.rbtnNormal.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    lblField.setVisible(true);
                    cbxField.setVisible(true);
                    lblFormula.setVisible(false);
                    txtFormula.setVisible(false);
                }
            });

            paneBtns.add(this.rbtnNormal);
            bg.add(this.rbtnNormal);

            this.rbtnPhoto = new JRadioButton("相片");
            this.rbtnPhoto.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    lblField.setVisible(true);
                    cbxField.setVisible(true);
                    lblFormula.setVisible(false);
                    txtFormula.setVisible(false);
                }
            });
            paneBtns.add(this.rbtnPhoto);
            bg.add(this.rbtnPhoto);

            this.rbtnFormula = new JRadioButton("公式");
            this.rbtnFormula.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    lblFormula.setVisible(true);
                    txtFormula.setVisible(true);
                    lblField.setVisible(false);
                    cbxField.setVisible(false);
                }
            });
            paneBtns.add(this.rbtnFormula);
            bg.add(this.rbtnFormula);

            JPanel content = new JPanel();
            content.setLayout(new FlowLayout(FlowLayout.LEFT));

            this.lblField = new JLabel("字段");
            content.add(this.lblField);
            this.cbxField = new JComboBox();
            this.cbxField.setPreferredSize(new Dimension(300, 24));
            content.add(cbxField);

            this.lblFormula = new JLabel("公式");
            this.lblFormula.setVisible(false);
            content.add(this.lblFormula);
            this.txtFormula = new JTextField();
            this.txtFormula.setPreferredSize(new Dimension(300, 24));
            this.txtFormula.setVisible(false);
            content.add(this.txtFormula);

            this.add(content, BorderLayout.CENTER);
        }

        private void populate(JsDataValue value) {
            int type = value.getType();

            if (type == JsDataValue.TYPE_FORMULA) {
                this.lblFormula.setVisible(true);
                this.txtFormula.setVisible(true);
                this.lblField.setVisible(false);
                this.cbxField.setVisible(false);
                this.rbtnFormula.setSelected(true);
                this.txtFormula.setText(value.getFormula());
            } else {
                this.lblField.setVisible(true);
                this.cbxField.setVisible(true);
                this.lblFormula.setVisible(false);
                this.txtFormula.setVisible(false);

                if (type == JsDataValue.TYPE_PHOTO) {
                    this.rbtnPhoto.setSelected(true);
                } else {
                    this.rbtnNormal.setSelected(true);
                }

                String id = value.getField();
                if (StringUtils.isEmpty(id)) {
                    return;
                }

                for (int i = 0, size = this.cbxField.getItemCount(); i < size; i++) {
                    @SuppressWarnings("unchecked")
                    IdName<String> item = (IdName<String>) cbxField.getItemAt(i);

                    if (id.equals(item.getId())) {
                        cbxField.setSelectedIndex(i);
                        break;
                    }
                }
            }
        }

        private void update(JsDataValue value) {
            if (this.rbtnFormula.isSelected()) {
                value.setType(JsDataValue.TYPE_FORMULA);
                value.setFormula(this.txtFormula.getText().trim());
            } else {
                @SuppressWarnings("unchecked")
                IdName<String> item = (IdName<String>) this.cbxField.getSelectedItem();

                if (item != null) {
                    value.setField(item.getId());
                    value.setFieldCaption(item.getName());
                }

                if (this.rbtnNormal.isSelected()) {
                    value.setType(JsDataValue.TYPE_NORMAL);
                } else {
                    value.setType(JsDataValue.TYPE_PHOTO);
                }
            }
        }
    }
}
